//////////////////////////////////////////////////////////////////////////
// $Id: Graph.cpp,v 1.1 2009/04/03 12:46:10 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////

	Graph::Graph()
	{
		mOpts[0] = MNEW((std::vector<OperationPtr>)); CHECK(mOpts[0]);
		mOpts[1] = MNEW((std::vector<OperationPtr>)); CHECK(mOpts[1]);
	}

	Graph::~Graph()
	{
		if(mOpts[0]) MDELETE(mOpts[0]);
		if(mOpts[1]) MDELETE(mOpts[1]);
	}

	//////////////////////////////////////////////////////////////////////////

	/*
	====================
	bind
	====================
	*/
	INLINE VOID Graph::bind( HWND wnd )
	{
		// clear all of the operation
		{
			THREAD_LOCK(&mOptsMutex)
			(*mOpts[0]).clear();
			(*mOpts[1]).clear();
		}

		// end the old thread
		if( alive() ) MThread::end();

		// bind a window handle for the context		
		Context::bind( wnd );

		// start the thread
		if( wnd ) MThread::start();
	}

	/*
	====================
	exec
	====================
	*/
	INLINE VOID Graph::exec( const Operation * op )
	{
		if(op) (*mOpts[0]).push_back((Operation*)op);
	}

	/*
	====================
	swap
	====================
	*/
	INLINE VOID Graph::swap()
	{
		{
			THREAD_LOCK(&mOptsMutex)

			// clear the operation buffer
			(*mOpts[1]).clear();

			// swap the operation buffer
			std::vector<OperationPtr>*temp_opts = mOpts[0];
			mOpts[0] = mOpts[1];
			mOpts[1] = temp_opts;
		}
	}

	//////////////////////////////////////////////////////////////////////////

	/*
	====================
	run
	====================
	*/
	INLINE VOID Graph::run()
	{
		// the render thread is running
		while( alive() )
		{
			// operation
			{
				THREAD_LOCK(&mOptsMutex)

				// exec all of the operation
				std::vector<OperationPtr>&opts = (*mOpts[1]);
				U32 size = opts.size();
				for( U32 i = 0; i < size; i++ ) 
					Context::exec( opts[i].ptr() );
			}
		}
	}

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////

